package com.net.xpay.openapi.interceptor;

import com.net.xpay.common.annotation.ApiMonitoring;
import com.net.xpay.common.model.monitor.AddApiMonitorDataModel;
import com.net.xpay.common.service.ApiMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Eric
 */
@Slf4j
public class ApiMonitoringInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private ApiMonitorService apiMonitorService;

    //用ThreadLocal记录当前线程访问接口的开始时间
    private final ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse rsp, Object handler) throws Exception {
        //记录请求开始时间
        startTime.set(System.currentTimeMillis());

        return super.preHandle(req, rsp, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse rsp, Object handler, Exception ex) {
        try {
            //接口路径 只统计对外的open api
            String url = req.getRequestURI();
            if (!url.contains("/openapi/") && !url.contains("/open/")) {
                return;
            }
            //接口名称
            String apiName = "";
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                ApiMonitoring methodAnnotation = handlerMethod.getMethodAnnotation(ApiMonitoring.class);
                if (methodAnnotation != null) {
                    apiName = methodAnnotation.value();
                } else {
                    log.info("apiMonitoringInterceptor postHandle no record|url={}", url);
                    return;
                }
            } else {
                return;
            }

            // 请求处理完毕，记录结束时间并计算耗时
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime.get();
            //处理完成后删除
            startTime.remove();

            //调用服务
            AddApiMonitorDataModel model = new AddApiMonitorDataModel();
            model.setApi(url);
            model.setApiName(apiName);
            model.setReqCostTime(executionTime);
            apiMonitorService.addMonitorData(model);
        } catch (Exception e) {
            log.warn("apiMonitoringInterceptor postHandle error", e);
        }
    }

}
